package com.xs.aifitnessagent.chatmemory;

import com.xs.aifitnessagent.service.MessageService;
import com.xs.aifitnessagent.util.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 基于MySQL数据库的对话记忆实现
 *
 * @author lambor
 */
@Component
@Slf4j
public class MysqlChatMemory implements ChatMemory {

    private final MessageService messageService;

    public MysqlChatMemory(MessageService messageService) {
        this.messageService = messageService;
    }

    /**
     * 添加消息到数据库
     *
     * @param conversationId 对话ID
     * @param messages Spring AI消息列表
     */
    @Override
    public void add(String conversationId, List<Message> messages) {
        if (messages.isEmpty()) {
            return;
        }

        try {
            Integer userIdInt = ThreadLocalUtil.getUserId();
            if (userIdInt == null) {
                log.warn("ThreadLocal中未找到用户ID，跳过消息保存: chatId={}", conversationId);
                return;
            }
            String userId = userIdInt.toString();

            // 遍历消息列表，根据类型保存到数据库
            for (Message message : messages) {
                if (message instanceof UserMessage userMessage) {
                    messageService.saveMessage(conversationId, userId, userMessage.getText(), "USER", null);
                    log.debug("通过ChatMemory保存用户消息: chatId={}, userId={}, content={}",
                             conversationId, userId, userMessage.getText());
                } else if (message instanceof AssistantMessage assistantMessage) {
                    // 对于助手消息，设置默认模型名称
                    messageService.saveMessage(conversationId, userId, assistantMessage.getText(), "ASSISTANT", "qwen-plus");
                    log.debug("通过ChatMemory保存助手消息: chatId={}, userId={}, content={}",
                             conversationId, userId, assistantMessage.getText());
                } else {
                    log.warn("未知的消息类型: {}", message.getClass().getSimpleName());
                }
            }

            log.info("通过ChatMemory成功保存{}条消息: chatId={}, userId={}", messages.size(), conversationId, userId);
        } catch (Exception e) {
            log.error("通过ChatMemory保存消息失败: chatId={}, error={}", conversationId, e.getMessage(), e);
            // 不抛出异常，避免影响AI对话流程
        }
    }

    /**
     * 从数据库获取消息
     *
     * @param conversationId 对话ID
     * @return Spring AI消息列表
     */
    @Override
    public List<Message> get(String conversationId) {
        try {
            Integer userIdInt = ThreadLocalUtil.getUserId();
            if (userIdInt == null) {
                log.warn("ThreadLocal中未找到用户ID，返回空消息列表: chatId={}", conversationId);
                return List.of();
            }
            String userId = userIdInt.toString();

            // 从数据库查询消息
            List<com.xs.aifitnessagent.entities.Message> dbMessages =
                messageService.getMessagesByChatId(conversationId, userId);

            // 转换为Spring AI消息格式
            List<Message> messages = dbMessages.stream()
                    .map(dbMsg -> {
                        if ("USER".equals(dbMsg.getMessageType())) {
                            return new UserMessage(dbMsg.getContent());
                        } else if ("ASSISTANT".equals(dbMsg.getMessageType())) {
                            return new AssistantMessage(dbMsg.getContent());
                        } else {
                            log.warn("未知的消息类型: {}", dbMsg.getMessageType());
                            return null;
                        }
                    })
                    .filter(msg -> msg != null)
                    .map(Message.class::cast)
                    .collect(Collectors.toList());

            log.info("通过ChatMemory获取{}条消息: chatId={}, userId={}", messages.size(), conversationId, userId);
            return messages;
        } catch (Exception e) {
            log.error("通过ChatMemory获取消息失败: chatId={}, error={}", conversationId, e.getMessage(), e);
            return List.of(); // 返回空列表，避免影响AI对话流程
        }
    }

    /**
     * 清除指定对话的所有消息
     *
     * @param conversationId 对话ID
     */
    @Override
    public void clear(String conversationId) {
        try {
            Integer userIdInt = ThreadLocalUtil.getUserId();
            if (userIdInt == null) {
                log.warn("ThreadLocal中未找到用户ID，跳过消息清除: chatId={}", conversationId);
                return;
            }
            String userId = userIdInt.toString();

            // 删除数据库中的消息
            messageService.deleteMessagesByChatId(conversationId, userId);

            log.info("通过ChatMemory成功清除对话消息: chatId={}, userId={}", conversationId, userId);
        } catch (Exception e) {
            log.error("通过ChatMemory清除对话消息失败: chatId={}, error={}", conversationId, e.getMessage(), e);
            // 不抛出异常，避免影响正常流程
        }
    }
}
